﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

using Subgurim.Controles;

namespace CorreoSocialWeb.Models
{
    [System.ComponentModel.DataAnnotations.Schema.Table("Calificaciones")]
    public class Calificacion
    {
        [Key]
        public int Id { get; set; }

        [System.ComponentModel.DataAnnotations.Schema.ForeignKey("Calificador")]
	    public int UsuarioCalificadorId	{ get; set; }
        [System.ComponentModel.DataAnnotations.Schema.ForeignKey("Calificado")]
	    public int UsuarioCalificadoId	{ get; set; }

	    public int Puntaje	{ get; set; }
        public string Comentarios { get; set; }

        [Association("Usuario", "UsuarioCalificadorId", "Id")]
        public Usuario Calificador { get; set; }

        [Association("Usuario", "UsuarioCalificadoId", "Id")]
        public Usuario Calificado { get; set; }

        [NotMapped]
        public PuntajeDeCalificacion PuntajeEnu
        {
            get
            {
                return (PuntajeDeCalificacion)this.Puntaje;
            }
            set
            {
                this.Puntaje = (int)value;
            }
        }

        public void EnviarMailCalificado()
        {
            this.Calificado.MandarMailTeCalificaron(this.Calificador, this.PuntajeEnu);
        }

        public static List<Calificacion> GetListaPorUsuario(int usuarioId)
        {
            return new CorreoSocialDbContext().Calificaciones
            .Include(x=>x.Calificador)
            .Include(x=>x.RutasDeEnvioDeMensajeroARemitente)
            .Include(x => x.RutasDeEnvioDeMensajeroARemitente.Select(y=>y.Ruta))
            .Include(x => x.RutasDeEnvioDeMensajeroARemitente.Select(y=>y.Envio))
            .Include(x => x.RutasDeEnvioDeRemitenteAMensajero)
            .Include(x => x.RutasDeEnvioDeRemitenteAMensajero.Select(y=>y.Ruta))
            .Include(x => x.RutasDeEnvioDeRemitenteAMensajero.Select(y=>y.Envio))
            .Where(x => x.UsuarioCalificadoId.Equals(usuarioId)).ToList();
        }

        [NotMapped]
        public string PuntajeString
        {
            get
            {
                return new EnumStringHelper().Get(this.PuntajeEnu);
            }
        }

        [NotMapped]
        public string CalificadorString
        {
            get
            {
                return this.Calificador.NombreReputacionString;
            }
        }

        [NotMapped]
        public RutaDeEnvio RutaDeEnvio 
        {
            get 
            {
                if (this.EsDeMensajeroARemitente)
                    return this.RutasDeEnvioDeMensajeroARemitente.First();
                else
                    return this.RutasDeEnvioDeRemitenteAMensajero.First();
            }
        }

        public IOrigenDestinoString ItemCalificado
        {
            get
            {
                if (this.EsDeMensajeroARemitente)
                    return this.RutaDeEnvio.Envio;
                else
                    return this.RutaDeEnvio.Ruta;
            }
        }

        public IOrigenDestinoString ItemCalificador
        {
            get
            {
                if (!this.EsDeMensajeroARemitente)
                    return this.RutaDeEnvio.Envio;
                else
                    return this.RutaDeEnvio.Ruta;
            }
        }

        [NotMapped]
        public string ItemCalificadorString
        {
            get
            {
                return string.Format("{0} {1}"
                    , this.ItemCalificador.GetType().Name
                    , this.ItemCalificador.OrigenDestinoString);
            }
        }

        [NotMapped]
        public string ItemCalificadoString
        {
            get
            {
                return string.Format("{0} {1}"
                    , this.ItemCalificado.GetType().Name
                    , this.ItemCalificado.OrigenDestinoString);
            }
        }


        [InverseProperty("CalificacionMensajeroRemitente")]
        public List<RutaDeEnvio> RutasDeEnvioDeMensajeroARemitente { get; set; }

        [InverseProperty("CalificacionRemitenteMensajero")]
        public List<RutaDeEnvio> RutasDeEnvioDeRemitenteAMensajero { get; set; }

        [NotMapped]
        public bool EsDeMensajeroARemitente
        {
            get
            {
                if (!this.RutasDeEnvioDeMensajeroARemitente.Any() && !this.RutasDeEnvioDeRemitenteAMensajero.Any()
                    ||
                    this.RutasDeEnvioDeMensajeroARemitente.Any() && this.RutasDeEnvioDeRemitenteAMensajero.Any()
                    )
                    throw new ApplicationException("No se entontró la ruta de una Calificación.");

                return this.RutasDeEnvioDeMensajeroARemitente.Any();
            }
        }

        [NotMapped]
        public bool EsDeRemitenteAMensajero
        {
            get
            {
                return !this.EsDeMensajeroARemitente;

            }
        }
    }

    public enum PuntajeDeCalificacion : int
    {
        SinCalificar = -1,
        Mala = 1,
        Regular = 2,
        Buena = 3,
        MuyBuena =  4,
        Excelente = 5
    }
}